<template>
  <div class="game-container">
    <!-- 等待房间状态 - 只在没有房间时显示 -->
    <div v-if="gameStatus === 'waiting' && !currentRoom" class="waiting-room">
      <div class="waiting-content">
        <h1>欢迎来到协作绘画游戏</h1>
        <p>请创建房间或加入现有房间开始游戏（支持单人模式）</p>

        <div class="action-buttons">
          <button class="action-btn create-btn" @click="showRoomDialog = true">
            <span class="btn-icon">🏠</span>
            创建房间
          </button>
          <button class="action-btn join-btn" @click="showRoomDialog = true">
            <span class="btn-icon">🚪</span>
            加入房间
          </button>
        </div>
      </div>
    </div>

    <!-- 游戏界面 - 包括房间准备就绪和游戏进行中 -->
    <div v-else>
      <!-- 网络状态提示 -->
      <div v-if="!isOnline || networkErrorCount > 0" class="network-warning">
        <span class="warning-icon">⚠️</span>
        <span v-if="!isOnline">网络连接已断开，当前为本地模式</span>
        <span v-else>网络连接不稳定，已切换到本地模式</span>
        <button @click="testNetworkConnection" class="test-network-btn" :disabled="isTestingNetwork">
          {{ isTestingNetwork ? '测试中...' : '测试网络' }}
        </button>
      </div>
      
      <!-- SignalR连接状态提示 -->
      <div v-if="showConnectionStatus" class="connection-status-banner" :class="connectionStatusClass">
        <div class="banner-content">
          <span class="status-icon">{{ connectionStatusIcon }}</span>
          <span class="status-text">{{ connectionStatusText }}</span>
          <button 
            v-if="canReconnect" 
            @click="reconnectSignalR" 
            class="reconnect-btn"
            :disabled="isReconnecting"
          >
            {{ isReconnecting ? '重连中...' : '重新连接' }}
          </button>
          <button 
            @click="testConnection" 
            class="test-connection-btn"
            :disabled="isReconnecting"
          >
            🔍 测试连接
          </button>
        </div>
      </div>
      
      <!-- 房间准备就绪提示条 -->
      <div v-if="gameStatus === 'waiting' && currentRoom" class="room-ready-banner">
        <div class="banner-content">
          <span class="banner-icon">🎯</span>
          <span class="banner-text">
            <span v-if="isCountingDown">游戏将在 {{ countdownLeft }} 秒后开始...</span>
            <span v-else-if="allPlayersReady">所有玩家已准备就绪，房主可以开始游戏！</span>
            <span v-else>等待玩家准备中... ({{ readyPlayerCount }}/{{ totalPlayerCount }})</span>
          </span>
          <button 
            v-if="isHost && allPlayersReady && !isCountingDown" 
            class="start-game-btn" 
            @click="startGame"
            :disabled="!canStartGame"
          >
            🎮 开始游戏
          </button>
          <!-- 非房主不再显示准备/取消准备按钮，统一显示提示文案 -->
          <span v-else-if="!isHost" class="waiting-text">
            ✅ 已准备，等待房主开始游戏...
          </span>
        </div>
      </div>
      
      <!-- 游戏进行中提示条（根据反馈，默认隐藏以节省空间） -->
      <div v-if="showPlayingBanner && gameStatus === 'playing'" class="game-playing-banner">
        <div class="banner-content">
          <span class="banner-icon">🎨</span>
          <span class="banner-text">游戏进行中 - 剩余时间: {{ formatTime(gameTime) }}</span>
          <div class="game-progress">
            <div class="progress-bar">
              <div class="progress-fill" :style="{ width: progressPercentage + '%' }"></div>
            </div>
            <span class="progress-text">{{ progressPercentage }}%</span>
          </div>
        </div>
      </div>
      
      <!-- 游戏结束提示条 -->
      <div v-if="gameStatus === 'finished'" class="game-finished-banner">
        <div class="banner-content">
          <span class="banner-icon">🏆</span>
          <span class="banner-text">
            游戏结束！获胜者: {{ winner?.name || '未知' }}
            <span v-if="isHost" class="host-actions">
              <button class="reset-btn" @click="resetGame">🔄 重新开始</button>
            </span>
          </span>
        </div>
      </div>
      
      <!-- 顶部控制栏 -->
      <div class="top-controls" :class="{ 
        'with-banner': (gameStatus === 'waiting' || gameStatus === 'ready' || gameStatus === 'finished') && currentRoom 
      }">
        <GameTopBar 
          :colors="colors" 
          :selected-color="selectedColor" 
          :brush-size="brushSize"
          @update:brush-size="brushSize = $event" 
          @toggle-stats="showStats = !showStats"
          @clear-paint="clearMyPaint"
          @show-room-info="showRoomInfo = true"
        />
      </div>


      <!-- 游戏界面内容 -->
      <div v-if="gameStatus === 'ready' || gameStatus === 'playing'" class="main-content">
        <!-- 左侧边栏 -->
        <GameLeftSidebar 
          :game-time="gameTime" 
          :game-status="gameStatus" 
          :players="players"
          :canvas-data="canvasData"
          @time-up="handleTimeUp"
          @game-finished="handleGameFinished"
          @area-stats-updated="handleAreaStatsUpdated"
        />

        <!-- 中央画布 -->
        <GameCanvas :selected-color="selectedColor" :brush-size="brushSize" :game-status="gameStatus"
          :canvas-data="canvasData" :canvas-data-version="canvasDataVersion" @pixel-added="handlePixelAdded"
          @canvas-initialized="handleCanvasInitialized" @canvas-stats-updated="handleCanvasStatsUpdated" />

        <!-- 玩家信息面板（右侧） -->
        <GamePlayersPanel 
          :players="players" 
          :max-players="currentRoom?.maxPlayers || 5"
          :game-status="gameStatus"
        />
      </div>

      <!-- 房间信息显示 -->
      <RoomInfo v-if="currentRoom || isMockMode" :visible="showRoomInfo" :room-id="currentRoom?.roomId || 'MOCK001'"
        :room-name="currentRoom?.roomName || '模拟房间'" :player-count="players.length" :max-players="currentRoom?.maxPlayers || 5"
        :game-status="gameStatus" @leave-room="handleLeaveRoom" @close="showRoomInfo = false" />
    </div>

    <!-- 房间管理弹窗 -->
    <RoomDialog :visible="showRoomDialog" :mock="true" @close="showRoomDialog = false" @room-created="handleRoomCreated"
      @room-joined="handleRoomJoined" />

    <!-- 游戏结束对话框 -->
    <GameOverDialog :visible="gameStatus === 'finished' || showGameOverDialog" @restart="handleRestart" />

    <!-- 调试信息面板 -->
    <div v-if="showDebugPanel" class="debug-panel">
      <h4>🔧 调试信息</h4>
      <div class="debug-item">
        <strong>Socket状态:</strong> 
        <span :class="socketManager.getConnectionStatus().status">
          {{ socketManager.getConnectionStatus().status }}
        </span>
      </div>
      <div class="debug-item">
        <strong>房间ID:</strong> {{ route.params.roomId || currentRoom.value?.roomId || 'N/A' }}
      </div>
      <div class="debug-item">
        <strong>已加入房间组:</strong> {{ socketManager.getCurrentJoinedRoomId() || 'N/A' }}
      </div>
      <div class="debug-item">
        <strong>数据源:</strong> {{ dataSource }}
      </div>
      <div class="debug-item">
        <strong>最后更新:</strong> {{ formatUpdateTime(lastDataUpdate) }}
      </div>
      <div class="debug-item">
        <strong>Canvas版本:</strong> {{ canvasDataVersion }}
      </div>
      <div class="debug-item">
        <strong>游戏状态:</strong> {{ gameStore.gameStatus }}
      </div>
      <div class="debug-item">
        <strong>房间状态:</strong> {{ roomStore.currentRoom?.status || 'N/A' }}
      </div>
      <div class="debug-item">
        <strong>当前玩家:</strong> {{ gameStore.currentPlayer?.name || 'N/A' }}
      </div>
      <div class="debug-item">
        <strong>玩家数量:</strong> {{ gameStore.players.length }}
      </div>
      <div class="debug-item">
        <strong>画布像素数:</strong> {{ Object.keys(gameStore.canvasData.pixels || {}).length }}
      </div>
             <button @click="forceReconnect" class="debug-btn">🔄 强制重连</button>
       <button @click="forceJoinRoom" class="debug-btn">🔗 强制加入房间组</button>
       <button @click="cleanupInvalidPlayers" class="debug-btn">🧹 清理无效玩家</button>
       <button @click="testPaintSync" class="debug-btn">🎨 测试绘画同步</button>
       <button @click="forceSyncCanvas" class="debug-btn">🔄 强制同步画布</button>
       <button @click="forceResetGameState" class="debug-btn">🔄 强制重置游戏状态</button>
       <button @click="forceCleanAllData" class="debug-btn">🧹 强制清理所有数据</button>
       <button @click="forceReinitSocket" class="debug-btn">🔌 强制重新初始化Socket</button>
       <button @click="resetSocketListeners" class="debug-btn">🎧 重置Socket事件监听器</button>
       <button @click="oneClickFixAll" class="debug-btn">🚀 一键修复所有问题</button>
       <button @click="forceRebuildConnection" class="debug-btn">🔨 强制重建连接</button>
       <button @click="diagnoseSocketConnection" class="debug-btn">🔍 诊断Socket连接</button>
       <button @click="testBackendConnection" class="debug-btn">🌐 测试后端连接</button>
       <button @click="forceRebuildAllConnections" class="debug-btn">⚡ 强制重建所有连接</button>
       <button @click="forceResetAllEventListeners" class="debug-btn">🎧 强制重置所有事件监听器</button>
       <button @click="forceTestPaintSync" class="debug-btn">🎨 强制测试绘画同步</button>
       <button @click="forceCleanupExtraPlayers" class="debug-btn">🧹 强制清理多余玩家</button>
       <button @click="forceRebuildCompleteConnection" class="debug-btn">🔧 强制重建完整连接</button>
       <button @click="forceResetAllEventListenersCompletely" class="debug-btn">🎧 强制完全重置事件监听器</button>
    </div>
  </div>
</template>

<script>
// 页面职责：
// - 展示游戏画布，处理绘画交互
// - 管理游戏状态（等待、进行中、结束）
// - 显示玩家统计和排行榜
// - 处理房间管理和游戏控制
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import { useUserStore } from '../stores/user'
import { useGameStore } from '../stores/game'
import { useRoomStore } from '../stores/room'
import socketManager, { GAME_EVENTS } from '../utils/socket'
import GameTopBar from '@/components/game/GameTopBar.vue'
import GameLeftSidebar from '@/components/game/GameLeftSidebar.vue'
import GameCanvas from '@/components/game/GameCanvas.vue'
import GameRightSidebar from '@/components/game/GameRightSidebar.vue'
import GamePlayersPanel from '@/components/game/GamePlayersPanel.vue'
import GameOverDialog from '@/components/game/GameOverDialog.vue'
import RoomInfo from '@/components/rooms/RoomInfo.vue'
import RoomDialog from '@/components/rooms/dialogs/RoomDialog.vue'
import { gameAPI } from '@/api' // 导入游戏API
import { useAudioStore } from '@/stores/audio'
import gameBgm from '@/assets/audio/游戏背景音乐.mp3'

export default {
  name: 'GameView',
  components: {
    GameTopBar,
    GameLeftSidebar,
    GameCanvas,
    GameRightSidebar,
    GamePlayersPanel,
    GameOverDialog,
    RoomInfo,
    RoomDialog
  },
  setup() {
    const router = useRouter()
    const route = useRoute()
    const userStore = useUserStore()
    const gameStore = useGameStore()
    const roomStore = useRoomStore()
    const audioStore = useAudioStore()

    // 游戏状态
    const gameStatus = ref('waiting')
    // 倒计时以全局 store 为准，避免各处各自计时导致不同步
    const gameTime = computed(() => gameStore.gameTime)
    const showPlayingBanner = ref(false)
    // 倒计时控制
    const isCountingDown = ref(false)
    const countdownLeft = ref(0)
    let countdownFallbackTimer = null
    let startFallbackTimer = null
    let enterGameFallbackTimer = null
    // 游戏数据
    const players = computed(() => gameStore.players)
    const canvasData = computed(() => gameStore.canvasData)
    
    // 添加缺失的变量和函数
    const showGameOverDialog = ref(false)
    // 防重复：结算历史只保存一次
    let hasSavedHistory = false

    const saveGameHistorySafely = async () => {
      try {
        if (hasSavedHistory) return
        const rid = route.params.roomId || currentRoom.value?.roomId
        const roomName = currentRoom.value?.roomName || ''
        // 以面积排序计算胜者
        const finalPlayers = gameStore.players.slice().map(p => ({ ...p, area: Number(p.area) || 0 }))
        const sorted = finalPlayers.sort((a,b) => b.area - a.area)
        const winner = sorted[0]
        const totalDurationSec = Number(gameStore.gameTotalDuration) || (Number(roomStore.currentRoom?.gameDuration) || 2) * 60
        const endAtMs = Date.now()
        const startAtMs = endAtMs - totalDurationSec * 1000 + (Number(gameStore.gameTime) || 0) * 1000
        // 工具：校验并归一化 GUID；如果本地玩家ID不是GUID，则尝试按昵称从房间成员映射
        const isGuid = (v) => typeof v === 'string' && /^(\{)?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(\})?$/.test(v)
        const mapNameToMemberId = (name) => {
          try {
            const members = roomStore.currentRoom?.members || []
            const m = members.find(m => String(m.name || m.username || m.nickname).toLowerCase() === String(name).toLowerCase())
            return m?.id || m?.userId || null
          } catch (_) { return null }
        }
        const toGuidOrNull = (id, name) => {
          if (isGuid(id)) return id
          const mapped = mapNameToMemberId(name)
          return isGuid(mapped) ? mapped : null
        }

        const safeWinnerId = toGuidOrNull(winner?.id, winner?.name)
        const record = {
          roomId: rid,
          roomName: roomName,
          // winnerId 仅在为有效GUID时发送，避免后端模型绑定400
          ...(safeWinnerId ? { winnerId: safeWinnerId } : {}),
          winnerUsername: winner?.name,
          playerCount: gameStore.players.length,
          // 后端期望分钟
          duration: Math.ceil(totalDurationSec / 60),
          startedAt: new Date(startAtMs).toISOString(),
          endedAt: new Date(endAtMs).toISOString(),
          status: 'Finished',
          playerResults: sorted.map((p, idx) => {
            const pid = toGuidOrNull(p.id, p.name)
            const item = {
              username: p.name,
              color: p.color,
              areaCount: Number(p.area) || 0,
              rank: idx + 1,
              isWinner: idx === 0
            }
            if (pid) item.playerId = pid
            return item
          })
        }
        await gameAPI.saveGameRecord(record)
        hasSavedHistory = true
      } catch (e) {
        // 静默失败，避免影响页面流程
        console.warn('保存游戏历史失败(忽略不中断):', e?.message)
        console.warn('错误详情:', {
          message: e?.message,
          response: e?.response?.data,
          status: e?.response?.status
        })
      }
    }
    
    // 强制从服务端拉取并对齐状态与时间
    const fetchAndSyncGameStatus = async (roomId) => {
      try {
        if (!roomId) return
        const resp = await gameAPI.getGameStatus(roomId)
        const data = resp?.data || resp
        const statusRaw = data?.status || data?.gameStatus
        const status = typeof statusRaw === 'string' ? statusRaw.toLowerCase() : undefined
        const startTimeStr = data?.startTime || data?.startedAt
        const durationSeconds = typeof data?.duration === 'number' ? data.duration : (typeof data?.totalDuration === 'number' ? data.totalDuration : undefined)
        const timeLeft = typeof data?.timeLeft === 'number' ? data.timeLeft : undefined
        const startTimeMs = startTimeStr ? new Date(startTimeStr).getTime() : undefined
        gameStore.updateGameStatus(status || 'playing', timeLeft, startTimeMs, durationSeconds)
        // 同步房间状态到 store 与大厅卡片
        try { roomStore.updateRoomStatus(roomId, status || 'playing') } catch (_) {}
      } catch (_) {}
    }
    
    // 处理游戏重新开始
    const handleRestart = () => {
      console.log('🔄 重新开始游戏')
      showGameOverDialog.value = false
      gameStatus.value = 'waiting'
      // 重置游戏状态
      gameStore.resetGame()
      ElMessage.success('游戏已重置，可以重新开始')
    }
    
    // 进入游戏界面
    const enterGame = async () => {
      const roomId = route.params.roomId || currentRoom.value?.roomId
      console.log('进入游戏界面，房间ID:', roomId)
      
      if (!roomId) {
        console.error('没有房间ID，无法进入游戏界面')
        ElMessage.error('无法获取房间信息')
        return
      }
      
      try {
        // 显示加载状态
        ElMessage.info('正在进入游戏界面...')
        
        // 调用后端API设置房间为准备状态
        const response = await gameAPI.setRoomReady(roomId)
        console.log('设置房间准备状态响应:', response)
        
        if (response && response.success !== false) {
          // 成功进入游戏界面
          gameStatus.value = 'ready'
          ElMessage.success('已进入游戏界面！')
          console.log('成功进入游戏界面')
        } else {
          ElMessage.error('进入游戏界面失败')
          console.error('设置房间准备状态失败:', response)
        }
      } catch (error) {
        console.error('进入游戏界面时发生错误:', error)
        ElMessage.error('进入游戏界面失败，请重试')
      }
    }
    
    // 开始游戏
    const startGame = async () => {
      const roomId = route.params.roomId || currentRoom.value?.roomId
      console.log('🎮 === 开始游戏调试信息 ===')
      console.log('房间ID:', roomId)
      console.log('当前游戏状态:', gameStatus.value)
      console.log('是否房主:', isHost.value)
      console.log('所有玩家准备状态:', allPlayersReady.value)
      console.log('可以开始游戏:', canStartGame.value)
      console.log('玩家列表:', JSON.stringify(gameStore.players, null, 2))
      console.log('当前用户:', userStore.user)
      console.log('路由参数:', route.params)
      console.log('当前房间:', currentRoom.value)
      
      if (!roomId) {
        console.error('❌ 没有房间ID，无法开始游戏')
        ElMessage.error('无法获取房间信息')
        return
      }
      
      if (!isHost.value) {
        console.error('❌ 只有房主可以开始游戏')
        ElMessage.error('只有房主可以开始游戏')
        return
      }
      
      if (!allPlayersReady.value) {
        console.error('❌ 还有玩家未准备就绪')
        ElMessage.error('请等待所有玩家准备就绪后再开始游戏')
        return
      }
      
      try {
        console.log('🚀 开始调用游戏开始逻辑...')
        
        // 不再弹出额外提示，避免"等待倒计时"卡在顶部
        
        // 调用游戏store开始游戏（现在通过SignalR）
        console.log('📞 调用 gameStore.startGame...')
        const result = await gameStore.startGame(roomId)
        console.log('✅ gameStore.startGame 调用完成，结果:', result)
        
        if (result) {
          console.log('🎉 游戏开始请求发送成功，等待服务器倒计时/开始事件')
          // 取消本地强制开始；仅提示并等待服务端倒计时/开始事件
          if (startFallbackTimer) { clearTimeout(startFallbackTimer); startFallbackTimer = null }
          // 保留一个轻提示/对齐：6秒后若仍未开始，则仅拉取状态，不本地开局
          startFallbackTimer = setTimeout(() => {
            const rid = route.params.roomId || currentRoom.value?.roomId
            fetchAndSyncGameStatus(rid)
          }, 6000)
        } else {
          ElMessage.error('游戏开始失败')
          console.error('❌ 游戏开始请求发送失败')
        }
        
      } catch (error) {
        console.error('❌ 开始游戏时发生错误:', error)
        console.error('错误详情:', {
          message: error.message,
          stack: error.stack,
          response: error.response
        })
        
        // 提供更友好的错误信息
        let errorMessage = '开始游戏失败，请重试'
        if (error.message.includes('网络连接失败')) {
          errorMessage = '网络连接失败，请检查网络并刷新页面重试'
        } else if (error.message.includes('实时连接断开')) {
          errorMessage = '实时连接断开，请刷新页面重试'
        } else if (error.message.includes('登录已过期')) {
          errorMessage = '登录已过期，请重新登录'
        } else if (error.message.includes('Socket状态异常')) {
          errorMessage = '连接状态异常，请刷新页面重试'
        }
        
        ElMessage.error(errorMessage)
      }
    }
    
    // 颜色选择器 - 锁定为玩家自己的颜色
    const colors = computed(() => {
      // 找到当前玩家
      const currentPlayer = gameStore.players.find(p => 
        p.name === userStore.user?.userName || p.name === '你'
      )
      
      console.log('当前玩家信息:', currentPlayer)
      console.log('用户信息:', userStore.user)
      
      if (currentPlayer && currentPlayer.color) {
        // 只显示玩家自己的颜色，不允许切换
        const lockedColor = [{
          name: '我的颜色',
          value: currentPlayer.color,
          locked: true // 标记为锁定状态
        }]
        console.log('使用玩家锁定颜色:', lockedColor)
        return lockedColor
      }
      
      // 如果没有找到玩家或颜色，返回默认颜色
      const defaultColor = [{
        name: '默认颜色',
        value: '#3B82F6',
        locked: true
      }]
      console.log('使用默认锁定颜色:', defaultColor)
      return defaultColor
    })
    
    // 选中的颜色 - 自动设置为玩家自己的颜色
    const selectedColor = computed(() => {
      const currentPlayer = gameStore.players.find(p => 
        p.name === userStore.user?.userName || p.name === '你'
      )
      const color = currentPlayer?.color || '#3B82F6'
      console.log('选中的颜色:', color, '来自玩家:', currentPlayer?.name)
      return color
    })
    
    // 活跃玩家数量
    const activePlayerCount = computed(() => gameStore.activePlayerCount)
    
    // 玩家准备状态
    const isReady = computed(() => {
      const currentPlayer = gameStore.players.find(p => 
        p.name === userStore.user?.userName || p.name === '你'
      )
      return currentPlayer?.isReady || false
    })
    
    // 是否房主
    const isHost = computed(() => {
      // 以房间 creatorId 为准
      const creatorId = roomStore.currentRoom?.creatorId || roomStore.currentRoom?.creator?.id
      const myId = userStore.user?.id || userStore.user?.userId || userStore.user?.Id
      if (creatorId && myId) return String(creatorId) === String(myId)
      // 回退：若还拿不到，尽量不误判为房主
      return false
    })
    
    // 所有玩家是否准备就绪
    const allPlayersReady = computed(() => gameStore.allPlayersReady)
    
    // 准备玩家数量
    const readyPlayerCount = computed(() => {
      return gameStore.players.filter(p => p.isReady).length
    })
    
    // 总玩家数量
    const totalPlayerCount = computed(() => {
      return gameStore.players.filter(p => p.isActive).length
    })
    
    // 是否可以开始游戏
    const canStartGame = computed(() => gameStore.canStartGame)
    
    // 游戏进度百分比
    const progressPercentage = computed(() => {
      if (gameStatus.value !== 'playing') return 0
      const totalTime = gameStore.gameTotalDuration
      const remainingTime = gameStore.gameTime
      return Math.max(0, Math.min(100, ((totalTime - remainingTime) / totalTime) * 100))
    })
    
    // 获胜者
    const winner = computed(() => {
      if (gameStatus.value !== 'finished') return null
      return gameStore.sortedPlayers[0]
    })
    
    // 格式化时间显示
    const formatTime = (seconds) => {
      const mins = Math.floor(seconds / 60)
      const secs = seconds % 60
      return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
    }
    
    // 切换准备状态
    const toggleReady = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (!roomId) {
          ElMessage.error('无法获取房间信息')
          return
        }
        
        const currentPlayer = gameStore.players.find(p => 
          p.name === userStore.user?.userName || p.name === '你'
        )
        
        if (!currentPlayer) {
          ElMessage.error('无法获取玩家信息')
          return
        }
        
        const newReadyState = !isReady.value
        console.log('🔄 切换准备状态:', {
          player: currentPlayer.name,
          currentState: isReady.value,
          newState: newReadyState,
          roomId: roomId
        })
        
        // 通过Socket发送准备状态
        if (socketManager.getConnectionStatus().isConnected) {
          await socketManager.playerReady({
            roomId: roomId,
            playerId: currentPlayer.id,
            isReady: newReadyState
          })
          console.log('✅ Socket准备状态已发送')
        } else {
          console.warn('⚠️ Socket未连接，无法发送准备状态')
        }
        
        // 更新本地状态
        gameStore.updatePlayerReady(currentPlayer.id, newReadyState)
        console.log('✅ 本地准备状态已更新')
        
        // 显示结果
        ElMessage.success(`已${newReadyState ? '准备' : '取消准备'}`)
        
        // 调试信息
        console.log('🔄 准备状态更新后:', {
          allPlayersReady: allPlayersReady.value,
          canStartGame: canStartGame.value,
          readyCount: readyPlayerCount.value,
          totalCount: totalPlayerCount.value
        })
      } catch (error) {
        console.error('切换准备状态失败:', error)
        ElMessage.error('切换准备状态失败')
      }
    }
    
    // 重置游戏
    const resetGame = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (!roomId) {
          ElMessage.error('无法获取房间信息')
          return
        }
        
        // 通过Socket重置画布
        if (socketManager.getConnectionStatus().isConnected) {
          await socketManager.resetCanvas(roomId)
        }
        
        // 重置本地游戏状态
        gameStore.resetGame()
        gameStatus.value = 'waiting'
        
        ElMessage.success('游戏已重置')
      } catch (error) {
        console.error('重置游戏失败:', error)
        ElMessage.error('重置游戏失败')
      }
    }
    
    // 游戏控制
    const brushSize = ref(3)
    const showStats = ref(false)
    // const showTip = ref(true) // 提示功能已移除
    const showRoomInfo = ref(false)
    const showRoomDialog = ref(false)
    
    // 实时数据状态
    const dataSource = ref('local') // local, websocket, polling
    const lastDataUpdate = ref(null)
    // 定时确保SignalR组关系（防止偶发掉组收不到广播）
    let ensureGroupTimer = null
    const startEnsureGroup = (roomId) => {
      if (!roomId) return
      if (ensureGroupTimer) clearInterval(ensureGroupTimer)
      // 先立即尝试一次加入组
      ;(async () => { try { if (socketManager.getConnectionStatus().isConnected) { await socketManager.joinRoom(roomId, userStore.userDisplayName) } } catch (_) {} })()

      // 然后每3秒确保一次，避免倒计时期间掉组收不到广播
      ensureGroupTimer = setInterval(async () => {
        try {
          if (socketManager.getConnectionStatus().isConnected) {
            await socketManager.joinRoom(roomId, userStore.userDisplayName)
          }
        } catch (_) {}
      }, 3000) // 每3秒确保一次（倒计时阶段更密集）
    }

    // 当前房间信息
    const currentRoom = computed(() => roomStore.currentRoom)

    // 模拟模式标志
    const isMockMode = ref(true)

    // 实时监听房间成员变化，更新游戏玩家列表
    watch(() => roomStore.currentRoom?.members, (newMembers) => {
      if (newMembers && Array.isArray(newMembers)) {
        console.log('检测到房间成员变化，更新游戏玩家列表:', newMembers)
        roomStore.updateGamePlayersFromMembers(gameStore)
      }
    }, { deep: true, immediate: true })

    // 监听房间状态变化（仅同步本地视图，不在这里二次触发开始游戏）
    watch(() => roomStore.currentRoom?.status, (newStatus) => {
      if (newStatus === 'playing') {
        console.log('房间状态变为游戏进行中（视图同步）')
        gameStatus.value = 'playing'
      } else if (newStatus === 'finished') {
        console.log('房间状态变为游戏结束（视图同步）')
        gameStore.endGame()
        gameStatus.value = 'finished'
      }
    })
    
    // 监听全局游戏状态：当计时器归零时，store 会切到 finished，这里同步弹出结算框
    watch(() => gameStore.gameStatus, (newStatus) => {
      if (newStatus === 'finished') {
        gameStatus.value = 'finished'
        showGameOverDialog.value = true
        // 结束态：彻底停止像素批处理与绘制相关的计时器
        try { if (pixelBatchTimer) { clearTimeout(pixelBatchTimer); pixelBatchTimer = null } } catch (_) {}
        try { if (countdownFallbackTimer) { clearTimeout(countdownFallbackTimer); countdownFallbackTimer = null } } catch (_) {}
        try { if (enterGameFallbackTimer) { clearTimeout(enterGameFallbackTimer); enterGameFallbackTimer = null } } catch (_) {}
        // 停止游戏背景音乐（若需要可在大厅自动恢复）
        try { audioStore.stopBackgroundMusic() } catch (_) {}
        // 重置所有成员为未准备，便于下一局
        try {
          const rid = route.params.roomId || currentRoom.value?.roomId
          if (rid) roomStore.setAllMembersReady(false)
        } catch (_) {}
        // 保存游戏历史
        saveGameHistorySafely()
      } else if (newStatus === 'playing') {
        gameStatus.value = 'playing'
        try { if (enterGameFallbackTimer) { clearTimeout(enterGameFallbackTimer); enterGameFallbackTimer = null } } catch (_) {}
        // 播放游戏背景音乐（使用打包后的资源URL，自动循环）
        try { audioStore.playBackgroundMusic(gameBgm) } catch (_) {}
      }
    })

    // 额外保险：直接监听剩余时间，一到 0 立刻结算（避免某些端未切到 finished）
    let lastGameTime = gameTime.value
    watch(() => gameTime.value, (t) => {
      try {
        if (t <= 0 && lastGameTime > 0) {
          if (gameStore.gameStatus !== 'finished') {
            gameStore.endGame()
          }
          gameStatus.value = 'finished'
          showGameOverDialog.value = true
          // 停止音乐、清理准备状态并保存历史
          try { audioStore.stopBackgroundMusic() } catch (_) {}
          try { const rid = route.params.roomId || currentRoom.value?.roomId; if (rid) roomStore.setAllMembersReady(false) } catch (_) {}
          saveGameHistorySafely()
        }
      } finally {
        lastGameTime = t
      }
    })

    // 当画布像素数量变化时，轻微防抖后重算所有玩家面积，确保"占领进度"无需等待手动涂一笔
    let areaRecalcTimer = null
    const scheduleAreaRecalc = () => {
      if (areaRecalcTimer) clearTimeout(areaRecalcTimer)
      areaRecalcTimer = setTimeout(() => {
        try { gameStore.recalculateAllPlayerAreas() } catch (_) {}
      }, 150)
    }
    watch(
      () => Object.keys(gameStore.canvasData.pixels || {}).length,
      () => { scheduleAreaRecalc() }
    )
    
    // 网络状态检测
    const isOnline = ref(navigator.onLine)
    const networkErrorCount = ref(0)
    const isTestingNetwork = ref(false)
    
    // 实时数据轮询
    const pollingInterval = ref(null)
    const isPolling = ref(false)
    const POLLING_INTERVAL = 5000 // 5秒轮询一次
    
    // 测试网络连接
    const testNetworkConnection = async () => {
      if (isTestingNetwork.value) return
      
      isTestingNetwork.value = true
      try {
        // 尝试访问一个简单的API端点来测试网络连接
        const response = await fetch('https://httpbin.org/get', { 
          method: 'GET',
          mode: 'no-cors',
          cache: 'no-cache'
        })
        
        // 如果能到达这里，说明网络连接正常
        isOnline.value = true
        networkErrorCount.value = 0
        console.log('网络连接测试成功')
      } catch (error) {
        console.warn('网络连接测试失败:', error.message)
        // 不立即设置为离线，因为可能是CORS或其他问题
      } finally {
        isTestingNetwork.value = false
      }
    }
    
    // 监听网络状态变化
    const handleOnline = () => {
      isOnline.value = true
      networkErrorCount.value = 0
      console.log('网络已连接')
    }
    
    const handleOffline = () => {
      isOnline.value = false
      console.log('网络已断开，切换到本地模式')
      // 网络断开时启动轮询
      startPolling()
    }

    // 开始轮询实时数据
    const startPolling = () => {
      if (isPolling.value) return
      
      isPolling.value = true
      console.log('开始轮询实时数据')
      
      pollingInterval.value = setInterval(async () => {
        try {
          await fetchRealTimeData()
        } catch (error) {
          console.warn('轮询获取数据失败:', error)
        }
      }, POLLING_INTERVAL)
    }

    // 停止轮询
    const stopPolling = () => {
      if (pollingInterval.value) {
        clearInterval(pollingInterval.value)
        pollingInterval.value = null
      }
      isPolling.value = false
      console.log('停止轮询实时数据')
    }

    // 获取实时数据
    const fetchRealTimeData = async () => {
      const roomId = route.params.roomId || currentRoom.value?.roomId
      if (!roomId) return

      try {
        // 获取房间信息：进行中时不再频繁获取，避免覆盖本地玩家静态信息
        if (gameStatus.value !== 'playing') {
          const roomInfo = await roomStore.fetchRoomInfo(roomId)
          if (roomInfo?.members) {
            gameStore.updateRoomMembers(roomInfo.members)
          }
        }

        // 获取画布数据
        const canvasData = await gameStore.fetchCanvasData(roomId)
        if (canvasData?.pixels) {
          // 更新画布数据
          Object.entries(canvasData.pixels).forEach(([key, pixel]) => {
            const [x, y] = key.split(',').map(Number)
            gameStore.updateCanvasPixel({
              x,
              y,
              color: pixel.color,
              playerName: pixel.player,
              brushSize: pixel.brushSize,
              timestamp: pixel.timestamp
            })
          })
        }

        // 仅在非进行中才拉取房间统计，避免覆盖本地实时统计
        if (gameStatus.value !== 'playing') {
          const roomStats = await gameStore.fetchRoomStats(roomId)
          if (roomStats?.playerStats) {
            roomStats.playerStats.forEach(stat => {
              const validScore = typeof stat.score === 'number' && !Number.isNaN(stat.score)
              const validArea = typeof stat.area === 'number' && !Number.isNaN(stat.area)
              if (validScore || validArea) {
                gameStore.updatePlayerScore(stat.playerId, validScore ? stat.score : undefined, validArea ? stat.area : undefined)
              }
            })
          }
        }

        console.log('轮询获取实时数据成功')
        // 更新数据源状态
        dataSource.value = 'polling'
        lastDataUpdate.value = new Date()
      } catch (error) {
        console.warn('轮询获取实时数据失败:', error)
      }
    }

    // 格式化更新时间已在下方定义

    // 🔧 平衡修复：适中的面积统计触发频率
    let pixelBatch = ref([])
    let pixelBatchTimer = null
    
    const processPixelBatch = () => {
      if (gameStore.gameStatus === 'finished') return
      if (pixelBatch.value.length === 0) return
      
      const batch = pixelBatch.value.splice(0)
      
      // 立即发送到服务器
      batch.forEach(pixel => {
        socketManager.paintAction({
          roomId: route.params.roomId || currentRoom.value?.roomId,
          playerId: userStore.user?.id || userStore.userId,
          x: pixel.x,
          y: pixel.y,
          color: pixel.color,
          tool: 'brush',
          timestamp: Date.now(),
          brushSize: pixel.brushSize || 1
        })
      })
    }

    // 启动像素批次定时器（1ms处理一次）
    const startPixelBatchTimer = () => {
      if (pixelBatchTimer) clearInterval(pixelBatchTimer)
      pixelBatchTimer = setInterval(() => {
        if (gameStore.gameStatus === 'finished') return
        if (pixelBatch.value.length > 0) {
          processPixelBatch()
        }
      }, 1) // 1ms处理一次
    }
    
    const handlePixelAdded = (pixelData) => {
      if (gameStore.gameStatus !== 'playing') return
      
      pixelBatch.value.push(pixelData)
      
      // 立即处理，无需等待
      if (pixelBatch.value.length >= 1) {
        processPixelBatch()
      }
    }

    // 处理画布初始化
    const handleCanvasInitialized = async () => {
      try {
        if (currentRoom.value?.roomId) {
          console.log('画布初始化，获取房间画布数据:', currentRoom.value.roomId)
          
          // 获取画布数据
          await gameStore.fetchCanvasData(currentRoom.value.roomId)
          
          // 重新计算面积统计
          if (gameStore.canvasData.pixels && Object.keys(gameStore.canvasData.pixels).length > 0) {
            console.log('画布数据获取成功，重新计算面积统计')
            gameStore.recalculateAllPlayerAreas()
          }
        }
      } catch (error) {
        console.error('初始化画布失败:', error)
      }
    }
    
    // 处理倒计时结束
    const handleTimeUp = (data) => {
      console.log('倒计时结束，计算获胜者:', data)
      
      // 更新游戏状态为结束
      gameStore.endGame()
      showGameOverDialog.value = true
      
      // 显示获胜者信息
      if (data.winner) {
        showWinnerAnnouncement(data.winner)
      }
    }
    
    // 处理游戏结束
    const handleGameFinished = (data) => {
      console.log('游戏结束:', data)
      
      // 更新游戏状态
      gameStore.endGame()
      showGameOverDialog.value = true
      
      // 最终计算所有玩家面积
      gameStore.recalculateAllPlayerAreas()
      
      // 保存游戏记录（后端亦会结算，这里保存用于历史展示）
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        const winner = gameStore.players.slice().sort((a,b)=>b.area-a.area)[0]
        
        // 工具：校验并归一化 GUID；如果本地玩家ID不是GUID，则尝试按昵称从房间成员映射
        const isGuid = (v) => typeof v === 'string' && /^(\{)?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(\})?$/.test(v)
        const mapNameToMemberId = (name) => {
          try {
            const members = roomStore.currentRoom?.members || []
            const m = members.find(m => String(m.name || m.username || m.nickname).toLowerCase() === String(name).toLowerCase())
            return m?.id || m?.userId || null
          } catch (_) { return null }
        }
        const toGuidOrNull = (id, name) => {
          if (isGuid(id)) return id
          const mapped = mapNameToMemberId(name)
          return isGuid(mapped) ? mapped : null
        }

        const safeWinnerId = toGuidOrNull(winner?.id, winner?.name)
        const record = {
          roomId: roomId,
          roomName: currentRoom.value?.roomName || '',
          // winnerId 仅在为有效GUID时发送，避免后端模型绑定400
          ...(safeWinnerId ? { winnerId: safeWinnerId } : {}),
          winnerUsername: winner?.name,
          playerCount: gameStore.players.length,
          duration: Math.ceil((gameStore.gameTotalDuration - gameStore.gameTime) / 60),
          startedAt: new Date(Date.now() - (gameStore.gameTotalDuration - gameStore.gameTime) * 1000).toISOString(),
          endedAt: new Date().toISOString(),
          status: 'Finished',
          playerResults: gameStore.players
            .slice()
            .sort((a,b)=>b.area-a.area)
            .map((p, idx) => {
              const pid = toGuidOrNull(p.id, p.name)
              const item = {
                username: p.name,
                color: p.color,
                areaCount: p.area || 0,
                rank: idx + 1,
                isWinner: idx === 0
              }
              if (pid) item.playerId = pid
              return item
            })
        }
        gameAPI.saveGameRecord(record).catch((e) => {
          console.warn('保存游戏历史失败(忽略不中断):', e?.message)
          console.warn('错误详情:', {
            message: e?.message,
            response: e?.response?.data,
            status: e?.response?.status
          })
        })
      } catch (e) {
        console.warn('构建游戏记录失败:', e?.message)
      }
      
      // 显示获胜者信息
      if (data.winner) {
        showWinnerAnnouncement(data.winner)
      }
    }
    
    // 处理面积统计更新
    const handleAreaStatsUpdated = (data) => {
      console.log('面积统计更新:', data)
      
      // 更新游戏store中的面积数据
      if (data.playerAreas && data.ranking) {
        gameStore.updatePlayerAreas(data.playerAreas, data.ranking)
      }
    }
    
    // 🔧 新增：处理画布统计更新
    const handleCanvasStatsUpdated = (statsData) => {
      console.log('画布统计更新:', statsData)
      
      // 根据颜色统计更新玩家面积
      if (statsData.colorStats && statsData.totalPixels > 0) {
        // 更新当前玩家的面积
        const currentPlayerName = userStore.userDisplayName
        const playerColor = statsData.playerColor
        
        // 找到匹配的颜色统计
        let playerPixels = 0
        Object.entries(statsData.colorStats).forEach(([color, count]) => {
          // 简单的颜色匹配（可以后续优化为更精确的匹配）
          if (color.includes('59, 130, 246') || color.includes('rgb(59, 130, 246)')) {
            playerPixels += count
          }
        })
        
        // 计算面积占比
        const percentage = Math.round((playerPixels / statsData.totalPixels) * 100 * 10) / 10
        
        // 更新游戏store中的玩家数据
        gameStore.updatePlayerStats(currentPlayerName, {
          area: playerPixels,
          score: percentage,
          isActive: true
        })
        
        console.log(`玩家 ${currentPlayerName} 面积统计: ${playerPixels}/${statsData.totalPixels} = ${percentage}%`)
      }
    }
    
    // 显示获胜者公告
    const showWinnerAnnouncement = (winner) => {
      // 创建获胜公告
      const announcement = document.createElement('div')
      announcement.className = 'winner-announcement'
      announcement.innerHTML = `
        <div class="winner-content">
          <div class="winner-icon">🏆</div>
          <div class="winner-text">
            <h3>恭喜 ${winner.name} 获胜！</h3>
            <p>占领面积: ${winner.percentage}%</p>
          </div>
        </div>
      `
      
      // 添加到页面
      document.body.appendChild(announcement)
      
      // 3秒后自动移除
      setTimeout(() => {
        if (announcement.parentNode) {
          announcement.parentNode.removeChild(announcement)
        }
      }, 3000)
    }

    // 清除我的绘画
    const clearMyPaint = async () => {
      try {
        if (currentRoom.value?.roomId) {
          // 先重置本地画布和统计
          gameStore.resetCanvas()
          
          // 然后调用API重置远程画布
          await gameStore.resetCanvasAPI(currentRoom.value.roomId)

          // 通过WebSocket发送重置画布
          if (socketManager.getConnectionStatus().isConnected) {
            socketManager.resetCanvas()
          }
          
          console.log('画布已清除，面积统计已重置')
        }
      } catch (error) {
        console.error('清除绘画失败:', error)
      }
    }

    // 显示房间信息
    const handleShowRoomInfo = () => {
      showRoomInfo.value = true
    }

    // 离开房间
    const handleLeaveRoom = async () => {
      try {
        if (currentRoom.value?.roomId) {
          await roomStore.leaveRoom(currentRoom.value.roomId)
          router.push('/')
        }
      } catch (error) {
        console.error('离开房间失败:', error)
      }
    }

    // 处理房间创建
    const handleRoomCreated = async (roomData) => {
      try {
        await roomStore.createRoom(roomData)
        showRoomDialog.value = false

        // 设置当前房间
        gameStore.setCurrentRoom(roomData.roomId, roomData.roomName, roomData.maxPlayers || 5, roomData.gameDuration)

        // 连接WebSocket
        await connectWebSocket()

        // 加入房间
        if (socketManager.getConnectionStatus().isConnected) {
          socketManager.joinRoom(roomData.roomId, userStore.userDisplayName)
        }
      } catch (error) {
        console.error('创建房间失败:', error)
      }
    }

    // 处理加入房间
    const handleRoomJoined = async (roomData) => {
      try {
        await roomStore.joinRoom(roomData.roomId)
        showRoomDialog.value = false

        // 设置当前房间
        gameStore.setCurrentRoom(roomData.roomId, roomData.roomName, roomData.maxPlayers || 5, roomData.gameDuration)

        // 连接WebSocket
        await connectWebSocket()

        // 加入房间
        if (socketManager.getConnectionStatus().isConnected) {
          socketManager.joinRoom(roomData.roomId, userStore.userDisplayName)
          
          // 如果玩家之前已经准备过，自动设置为已准备状态
          // 这样可以避免玩家进入游戏界面后还需要重新准备
          setTimeout(async () => {
            const currentPlayer = gameStore.players.find(p => 
              p.name === userStore.user?.userName || p.name === '你'
            )
            
            if (currentPlayer && !currentPlayer.isReady) {
              console.log('🔄 玩家进入游戏界面，自动设置为已准备状态')
              try {
                await socketManager.playerReady({
                  roomId: roomData.roomId,
                  playerId: currentPlayer.id,
                  isReady: true
                })
                gameStore.updatePlayerReady(currentPlayer.id, true)
                console.log('✅ 玩家已自动设置为准备状态')
              } catch (error) {
                console.warn('⚠️ 自动设置准备状态失败:', error)
              }
            }
          }, 1000) // 延迟1秒，确保玩家数据已加载
        }
      } catch (error) {
        console.error('加入房间失败:', error)
      }
    }

    // 连接WebSocket
    const connectWebSocket = async () => {
      try {
        if (!socketManager.getConnectionStatus().isConnected) {
          console.log('🔌 尝试连接 WebSocket...')
          await socketManager.connect() // 不需要传递token，会自动从localStorage获取
          console.log('✅ WebSocket 连接成功')
        } else {
          console.log('✅ WebSocket 已连接')
        }
        
        // 🔧 新增：确保加入房间组
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (roomId) {
          console.log('🔗 确保加入房间组:', roomId)
          const joinSuccess = await socketManager.ensureJoinRoomGroup(roomId)
          if (joinSuccess) {
            console.log('✅ 成功加入房间组:', roomId)
          } else {
            console.warn('⚠️ 加入房间组失败:', roomId)
          }
        }
        
        // 注意：事件监听器已经在页面加载时设置，这里不需要重复设置
        console.log('🎧 WebSocket 连接完成')
        
      } catch (error) {
        console.error('❌ 连接WebSocket失败:', error)
        // WebSocket连接失败不影响基本功能，继续执行
        console.warn('⚠️ WebSocket连接失败，但游戏功能仍可正常使用')
        // 重新抛出错误，让调用者知道连接失败
        throw error
      }
    }

    // 设置WebSocket监听器
    const setupWebSocketListeners = () => {
      // 防止重复设置监听器
      if (window._gameViewListenersSetup) {
        console.log('🎧 Socket 事件监听器已设置，跳过重复设置')
        return
      }
      window._gameViewListenersSetup = true
      
      console.log('🎧 开始设置 Socket 事件监听器...')
      
      // 监听房间加入
      socketManager.on(GAME_EVENTS.ROOM_JOINED, (data) => {
        console.log('成功加入房间:', data)
        // 更新房间成员列表
        if (data.members) {
          gameStore.updateRoomMembers(data.members)
        }
        // 更新数据源状态
        dataSource.value = 'websocket'
        lastDataUpdate.value = new Date()
      })

      // 监听玩家加入
      socketManager.on(GAME_EVENTS.PLAYER_JOINED, (data) => {
        console.log('新玩家加入:', data)
        // 更新玩家数据
        if (data.player) {
          console.log('玩家数据详情:', {
            id: data.player.id,
            name: data.player.username || data.player.name,
            color: data.player.color,
            avatar: data.player.avatar
          })
          gameStore.updatePlayerData(data.player)
        }
      })

      // 监听玩家离开
      socketManager.on('PlayerLeft', (data) => {
        console.log('玩家离开:', data)
        // 从玩家列表中移除玩家
        if (data.playerId) {
          const playerIndex = gameStore.players.findIndex(p => p.id === data.playerId)
          if (playerIndex !== -1) {
            gameStore.players.splice(playerIndex, 1)
          }
        }
      })

      // 监听玩家准备状态变化
      socketManager.on('PlayerReadyChanged', (data) => {
        console.log('玩家准备状态变化 (PlayerReadyChanged):', data)
        if (data.playerId && data.isReady !== undefined) {
          const player = gameStore.players.find(p => p.id === data.playerId)
          if (player) {
            player.isReady = data.isReady
            console.log(`✅ 玩家 ${player.name} 准备状态已更新为: ${data.isReady}`)
          }
        }
      })
      
      // 监听玩家准备状态变化（新事件名）
      socketManager.on('MemberReadyChanged', (data) => {
        console.log('玩家准备状态变化 (MemberReadyChanged):', data)
        if (data.playerId && data.isReady !== undefined) {
          const player = gameStore.players.find(p => p.id === data.playerId)
          if (player) {
            player.isReady = data.isReady
            console.log(`✅ 玩家 ${player.name} 准备状态已更新为: ${data.isReady}`)
          }
        }
      })

      // 监听游戏状态更新
      socketManager.on('GameStatusUpdated', (data) => {
        console.log('游戏状态更新:', data)
        const startTimeMs = data?.startTime ? new Date(data.startTime).getTime() : undefined
        const durationSeconds = typeof data?.duration === 'number' ? data.duration : undefined
        gameStore.updateGameStatus(data.status, data.timeLeft, startTimeMs, durationSeconds)
        // 同步房间状态
        try {
          const rid = route.params.roomId || currentRoom.value?.roomId
          if (rid && data?.status) roomStore.updateRoomStatus(rid, data.status)
        } catch (_) {}
        // 若关键字段缺失，拉一次权威状态
        if (!startTimeMs || !durationSeconds) {
          const rid = route.params.roomId || currentRoom.value?.roomId
          fetchAndSyncGameStatus(rid)
        }
      })

      // 直接监听SignalR游戏开始事件
      socketManager.on('GameStarted', (data) => {
        console.log('🎮 收到游戏开始事件:', data)
        console.log('🎮 当前游戏状态:', gameStatus.value)
        console.log('🎮 房间信息:', currentRoom.value)
        console.log('🎮 Socket连接状态:', socketManager.getConnectionStatus())
        
        try { ElMessage.closeAll() } catch (_) {}
        const roomId = route.params.roomId || currentRoom.value?.roomId || data.roomId
        
        // 更新游戏状态和时间
        const status = (data && data.gameStatus) ? data.gameStatus : 'playing'
        const timeLeft = (data && typeof data.timeLeft === 'number') ? data.timeLeft : undefined
        const startTimeMs = (data && data.startTime) ? new Date(data.startTime).getTime() : undefined
        const durationSeconds = (data && typeof data.duration === 'number') ? data.duration : undefined
        gameStore.updateGameStatus(status, timeLeft, startTimeMs, durationSeconds)

        // 本地视图状态与服务端同步
        gameStatus.value = 'playing'
        console.log('🎮 游戏状态已更新为:', gameStatus.value)
        
        // 任何倒计时提示在开始后立即清除
        isCountingDown.value = false
        countdownLeft.value = 0
        if (countdownFallbackTimer) { clearTimeout(countdownFallbackTimer); countdownFallbackTimer = null }
        if (startFallbackTimer) { clearTimeout(startFallbackTimer); startFallbackTimer = null }
        // 同步房间状态，避免其他依赖处仍显示"等待中"
        if (roomStore.currentRoom) {
          roomStore.currentRoom.status = 'playing'
        }
        // 根据反馈默认不显示进行中横幅
        showPlayingBanner.value = false
        
        // 同步用户头像和分配颜色
        if (roomStore.currentRoom?.members) {
          gameStore.syncUserAvatarsAndColors(roomStore.currentRoom.members, userStore)
        }
        // 游戏开始后停止密集保证入组
        if (ensureGroupTimer) { clearInterval(ensureGroupTimer); ensureGroupTimer = null }
        // 若服务端未携带 startTime/duration，则补一次权威对齐
        if (!startTimeMs || !durationSeconds) {
          const rid = route.params.roomId || currentRoom.value?.roomId || data?.roomId
          fetchAndSyncGameStatus(rid)
        }
      })

      // 监听开始游戏失败
      socketManager.on('GameStartFailed', (data) => {
        console.error('开始游戏失败(服务端):', data)
        const msg = data?.message || '开始游戏失败'
        ElMessage.error(msg)
      })

      // 直接监听SignalR倒计时事件
      socketManager.on('GameCountdown', (data) => {
        console.log('⏰ 收到倒计时事件:', data)
        console.log('⏰ 当前游戏状态:', gameStatus.value)
        console.log('⏰ Socket连接状态:', socketManager.getConnectionStatus())
        
        const countdown = (data && typeof data.countdown === 'number') ? data.countdown : undefined
        if (countdown && countdown > 0) {
          // 顶部仅保留横幅，不再保留持久消息，避免开始后仍显示
          try { ElMessage.closeAll() } catch (_) {}
          // 倒计时阶段同步进入准备态，避免只房主推进
          try { gameStatus.value = 'ready' } catch (_) {}
          console.log('⏰ 游戏状态已更新为准备态:', gameStatus.value)
          
          // 密集确保加入组
          const rid = route.params.roomId || currentRoom.value?.roomId || data?.roomId
          startEnsureGroup(rid)
          // 本地倒计时显示，仅作为UI提示，不触发开始
          isCountingDown.value = true
          countdownLeft.value = countdown
          const tick = setInterval(() => {
            countdownLeft.value = Math.max(0, countdownLeft.value - 1)
            if (countdownLeft.value <= 0) {
              clearInterval(tick)
              isCountingDown.value = false
            }
          }, 1000)
          // 倒计时结束不做任何本地强启动作，仅等待服务端 GameStarted
          if (countdownFallbackTimer) { clearTimeout(countdownFallbackTimer) }
          countdownFallbackTimer = setTimeout(() => {
            const rid = route.params.roomId || currentRoom.value?.roomId || data?.roomId
            fetchAndSyncGameStatus(rid)
          }, (countdown + 1) * 1000)
        }
      })

      // 🔧 修复：统一处理绘画事件，避免重复监听
      // 移除window事件监听器，统一使用socket事件
      // window.addEventListener('PaintAction', (evt) => { ... }) // 删除这行

      // 监听远程绘画动作 - 这是唯一处理PaintAction的地方
      socketManager.on('PaintAction', (data) => {
        console.log('🎨 收到远程绘画动作 (统一处理):', data)
        console.log('🎨 当前游戏状态:', gameStore.gameStatus)
        console.log('🎨 Socket连接状态:', socketManager.getConnectionStatus())
        console.log('🎨 当前房间ID:', route.params.roomId || currentRoom.value?.roomId)
        console.log('🎨 已加入房间组:', socketManager.getCurrentJoinedRoomId())
        
        if (gameStore.gameStatus !== 'playing') {
          console.log('❌ 游戏状态不是 playing，忽略绘画动作')
          return
        }
        console.log('✅ 游戏状态正确，处理绘画动作')
        
        // 检查是否是本地绘画动作（通过playerId判断）
        const currentUserId = userStore.user?.id || userStore.userId
        console.log('🎨 当前用户ID:', currentUserId)
        console.log('🎨 绘画动作用户ID:', data.playerId)
        
        if (data.playerId === currentUserId) {
          console.log('🔄 这是本地绘画动作，跳过重复处理')
          return
        }
        
        console.log('✅ 这是远程绘画动作，开始处理...')
        
        // 更新画布显示
        gameStore.updateCanvasPixel({
          x: data.x,
          y: data.y,
          color: data.color,
          playerName: data.playerName,
          playerId: data.playerId,
          brushSize: data.brushSize,
          timestamp: data.timestamp
        })
        
        // 更新Canvas版本号触发重绘
        try { 
          canvasDataVersion.value++ 
          console.log('📈 Canvas 版本号已更新:', canvasDataVersion.value)
        } catch (e) { 
          console.error('❌ 更新 Canvas 版本号失败:', e)
        }
        
        // 更新玩家分数（如果有）
        if (data.playerId && data.score === undefined) {
          try {
            const p = gameStore.players.find(p => String(p.id) === String(data.playerId))
            if (p) { 
              p.area = (Number(p.area) || 0) + 1; 
              gameStore.recalculateScores() 
            }
          } catch (_) {}
        }
        
        console.log('✅ 远程绘画动作处理完成')
      })

      // 监听画布重置（后端事件名为 CanvasReset）
      const onCanvasCleared = (data) => {
        console.log('画布已重置:', data)
        gameStore.resetCanvas()
      }
      socketManager.on(GAME_EVENTS.CANVAS_CLEARED, onCanvasCleared)
      socketManager.on('CanvasReset', onCanvasCleared)

      // 直接监听SignalR游戏结束事件
      socketManager.on('GameEnded', (data) => {
        console.log('游戏结束:', data)
        gameStore.endGame()
        try { if (pixelBatchTimer) { clearInterval(pixelBatchTimer); pixelBatchTimer = null } } catch (_) {}
        try { pixelBatch.value = [] } catch (_) {}
        // 弹出结算框
        showGameOverDialog.value = true
        // 更新最终游戏结果
        if (data.winner) {
          console.log('游戏获胜者:', data.winner)
        }
      })

      // 监听玩家分数更新
      socketManager.on('PlayerScoreUpdated', (data) => {
        console.log('玩家分数更新:', data)
        if (data.playerId && data.score !== undefined) {
          gameStore.updatePlayerScore(data.playerId, data.score, data.area)
        }
      })

      // 监听排行榜更新（后端事件名：LeaderboardUpdated）
      socketManager.on('LeaderboardUpdated', (data) => {
        if (gameStore.gameStatus !== 'playing') return
        console.log('排行榜更新:', data)
        if (data && data.leaderboard) {
          try { gameStore.handleLeaderboardUpdated(data) } catch (e) { console.warn('处理排行榜更新失败', e) }
        }
      })

      // 监听房间成员更新
      socketManager.on('RoomMembersUpdated', (data) => {
        console.log('房间成员更新:', data)
        if (data.members) {
          gameStore.updateRoomMembers(data.members)
          // 同步用户头像和分配颜色
          gameStore.syncUserAvatarsAndColors(data.members, userStore)
        }
      })

      // 监听房间状态变化
      socketManager.on('RoomStatusChanged', (data) => {
        console.log('房间状态变化:', data)
        if (data.status) {
          // 若本地已处于进行中或结束，忽略回退到 Ready 的状态，避免出现"已在游戏中仍显示倒计时"的问题
          if ((gameStatus.value === 'playing' || gameStore.gameStatus === 'playing') && data.status !== 'Playing') {
            console.log('忽略回退状态变更:', data.status)
            return
          }
          // 更新游戏状态
          if (data.status === 'Ready') {
            gameStatus.value = 'ready'
            console.log('房间状态已更新为准备就绪')
          } else if (data.status === 'Playing') {
            try { ElMessage.closeAll() } catch (_) {}
            gameStatus.value = 'playing'
            // 清理倒计时UI
            isCountingDown.value = false
            countdownLeft.value = 0
            console.log('房间状态已更新为游戏中')
          } else if (data.status === 'Finished') {
            gameStatus.value = 'finished'
            console.log('房间状态已更新为已结束')
          }
        }
      })
      
      console.log('🎧 Socket 事件监听器设置完成')
    }

    // 开始模拟游戏（用于测试）
    const startMockGame = () => {
      const roomId = route.params.roomId || currentRoom.value?.roomId
      gameStore.startGame(roomId)
    }

    // 获取实际玩家数量（基于画布数据）
    const getActualPlayerCount = () => {
      if (!canvasData.value.pixels || Object.keys(canvasData.value.pixels).length === 0) {
        return 1 // 至少有一个玩家（当前用户）
      }
      
      // 统计画布上有像素的不同玩家数量
      const uniquePlayers = new Set()
      Object.values(canvasData.value.pixels).forEach(pixel => {
        if (pixel.player) {
          uniquePlayers.add(pixel.player)
        }
      })
      
      return Math.max(1, uniquePlayers.size)
    }
    
    // 调试画布
    const debugCanvas = () => {
      console.log('=== 画布调试信息 ===')
      console.log('画布数据:', canvasData.value)
      console.log('玩家统计:', players.value)
      console.log('总面积:', players.value.reduce((sum, p) => sum + p.area, 0))
      console.log('像素数量:', Object.keys(canvasData.value.pixels).length)
      console.log('实际玩家数量:', getActualPlayerCount())
      
      // 按玩家统计像素
      const playerPixelCounts = {}
      Object.values(canvasData.value.pixels).forEach(pixel => {
        const playerName = pixel.player
        if (!playerPixelCounts[playerName]) {
          playerPixelCounts[playerName] = 0
        }
        playerPixelCounts[playerName]++
      })
      console.log('各玩家像素数:', playerPixelCounts)
      
      // 强制重新计算面积统计
      console.log('强制重新计算面积统计...')
      gameStore.recalculateAllPlayerAreas()
      
      console.log('重新计算后的玩家统计:', players.value)
      console.log('重新计算后的总面积:', players.value.reduce((sum, p) => sum + p.area, 0))
    }

    // 定时器句柄（在组件作用域，便于卸载时清理）
    let resetNetworkErrorTimer = null

    // 连接状态监控
    const isReconnecting = ref(false)
    const showConnectionStatus = ref(false)
    
    // 连接状态相关的计算属性
    const connectionStatus = computed(() => {
      try {
        return socketManager.getConnectionStatus()
      } catch (error) {
        console.error('获取连接状态失败:', error)
        return { isConnected: false, status: 'error', socketState: 'Unknown' }
      }
    })
    
    const connectionStatusClass = computed(() => {
      if (isReconnecting.value) return 'reconnecting'
      if (!connectionStatus.value.isConnected) return 'disconnected'
      return 'connected'
    })
    
    const connectionStatusIcon = computed(() => {
      if (isReconnecting.value) return '🔄'
      if (!connectionStatus.value.isConnected) return '❌'
      return '✅'
    })
    
    const connectionStatusText = computed(() => {
      if (isReconnecting.value) return '正在重新连接...'
      if (!connectionStatus.value.isConnected) return '实时连接已断开'
      return '实时连接正常'
    })
    
    const canReconnect = computed(() => {
      return !connectionStatus.value.isConnected && !isReconnecting.value
    })
    
    // 重连方法
    const reconnectSignalR = async () => {
      if (isReconnecting.value) return
      
      isReconnecting.value = true
      showConnectionStatus.value = true
      
      try {
        console.log('🔄 手动重连SignalR...')
        await socketManager.reconnect()
        console.log('✅ 手动重连成功')
        ElMessage.success('连接已恢复')
      } catch (error) {
        console.error('❌ 手动重连失败:', error)
        ElMessage.error('重连失败，请刷新页面重试')
      } finally {
        isReconnecting.value = false
      }
    }
    
    // 测试连接方法
    const testConnection = async () => {
      try {
        console.log('🔍 开始测试SignalR连接...')
        
        // 获取当前连接状态
        const status = socketManager.getConnectionStatus()
        console.log('当前连接状态:', status)
        
        // 尝试连接
        if (!status.isConnected) {
          console.log('连接未建立，尝试连接...')
          await socketManager.connect()
          console.log('连接尝试完成')
          
          // 等待连接稳定
          await new Promise(resolve => setTimeout(resolve, 1000))
          
          // 再次检查状态
          const newStatus = socketManager.getConnectionStatus()
          console.log('连接后状态:', newStatus)
          
          if (newStatus.isConnected) {
            ElMessage.success('连接测试成功！')
          } else {
            ElMessage.error('连接测试失败，状态: ' + newStatus.socketState)
          }
        } else {
          ElMessage.success('连接已建立，状态正常！')
        }
        
        // 显示详细状态信息
        console.log('🔍 详细连接信息:', {
          status,
          userAgent: navigator.userAgent,
          url: window.location.href,
          timestamp: new Date().toISOString()
        })
        
      } catch (error) {
        console.error('❌ 连接测试失败:', error)
        ElMessage.error('连接测试失败: ' + error.message)
      }
    }
    
    // 自动设置玩家准备状态
    const autoSetPlayerReady = async (roomId) => {
      try {
        // 延迟执行，确保玩家数据已加载
        setTimeout(async () => {
          const currentPlayer = gameStore.players.find(p => 
            p.name === userStore.user?.userName || p.name === '你'
          )
          
          if (currentPlayer && !currentPlayer.isReady && socketManager.getConnectionStatus().isConnected) {
            console.log('🔄 玩家进入游戏界面，自动设置为已准备状态')
            try {
              await socketManager.playerReady({
                roomId: roomId,
                playerId: currentPlayer.id,
                isReady: true
              })
              gameStore.updatePlayerReady(currentPlayer.id, true)
              console.log('✅ 玩家已自动设置为准备状态')
            } catch (error) {
              console.warn('⚠️ 自动设置准备状态失败:', error)
            }
          }
        }, 2000) // 延迟2秒，确保所有数据都已加载
      } catch (error) {
        console.error('自动设置准备状态时发生错误:', error)
      }
    }

    // 监控连接状态变化
    const startConnectionMonitoring = () => {
      const checkConnection = () => {
        const status = connectionStatus.value
        console.log('🔍 连接状态检查:', status)
        
        if (!status.isConnected && !showConnectionStatus.value) {
          showConnectionStatus.value = true
          console.log('⚠️ 检测到连接断开，显示状态提示')
        } else if (status.isConnected && showConnectionStatus.value) {
          // 连接恢复后延迟隐藏状态提示
          setTimeout(() => {
            showConnectionStatus.value = false
            console.log('✅ 连接恢复，隐藏状态提示')
          }, 3000)
        }
      }
      
      // 立即检查一次
      checkConnection()
      
      // 每5秒检查一次连接状态
      const connectionCheckInterval = setInterval(checkConnection, 5000)
      
      // 返回清理函数
      return () => {
        clearInterval(connectionCheckInterval)
      }
    }

    // 页面加载时初始化
    onMounted(async () => {
      // 添加网络状态监听器
      window.addEventListener('online', handleOnline)
      window.addEventListener('offline', handleOffline)
      
      // 添加网络错误计数自动重置定时器
      resetNetworkErrorTimer = setInterval(() => {
        if (networkErrorCount.value > 0) {
          networkErrorCount.value = Math.max(0, networkErrorCount.value - 1)
          console.log('网络错误计数自动减少:', networkErrorCount.value)
        }
      }, 30000) // 每30秒自动减少1个错误计数
      
      // 初始化用户状态
      await userStore.init()

      // 如果没有登录，跳转到登录页
      if (!userStore.isAuthenticated) {
        router.push('/login')
        return
      }

      // 首先建立SignalR连接，无论是否有房间信息
      console.log('🌐 网络状态检查:', isOnline.value ? '在线' : '离线')
      console.log('🔑 用户认证状态:', userStore.isAuthenticated)
      console.log('🎫 Token状态:', !!userStore.token?.accessToken)
      
      if (isOnline.value) {
        try {
          console.log('🔌 建立SignalR连接...')
          await connectWebSocket()
          console.log('✅ SignalR连接已建立')
          
          // 连接成功后再设置事件监听器
          setupWebSocketListeners()
          console.log('🎧 Socket 事件监听器已设置')
          
          // 启动连接状态监控
          const stopConnectionMonitoring = startConnectionMonitoring()
          console.log('🔍 连接状态监控已启动')
        } catch (wsError) {
          console.error('❌ SignalR连接失败:', wsError)
          console.error('连接失败详情:', {
            message: wsError.message,
            stack: wsError.stack,
            type: wsError.constructor.name
          })
          console.warn('⚠️ SignalR连接失败，但继续加载游戏页面')
          
          // 即使连接失败也设置监听器，以防后续重连成功
          setupWebSocketListeners()
          console.log('🎧 Socket 事件监听器已设置（连接失败状态）')
        }
      } else {
        console.warn('⚠️ 网络离线，跳过SignalR连接')
        // 离线状态也设置监听器
        setupWebSocketListeners()
        console.log('🎧 Socket 事件监听器已设置（离线状态）')
      }

      // 检查是否有房间ID参数或当前房间信息
      const roomId = route.params.roomId
      console.log('游戏页面初始化，房间ID参数:', roomId)
      console.log('当前房间信息:', roomStore.currentRoom)
      console.log('网络状态:', isOnline.value ? '在线' : '离线')
      
      if (roomId && roomId !== 'undefined') {
        try {
          console.log('通过URL参数获取房间信息:', roomId)
          const infoResult = await roomStore.fetchRoomInfo(roomId)
          if (!roomStore.currentRoom) {
            // 房间不存在或已删除
            ElMessage.warning('房间不存在或已被删除')
            // 不设置当前房间，停留在等待/创建界面
            return
          }
          gameStore.setCurrentRoom(roomId, roomStore.currentRoom?.roomName || '', roomStore.currentRoom?.maxPlayers || 5, roomStore.currentRoom?.gameDuration)

          // 确保已加入SignalR房间组，建立连接ID到玩家ID的映射
          if (socketManager.getConnectionStatus().isConnected) {
            console.log('加入SignalR房间组以建立映射...')
            await socketManager.joinRoom(roomId, userStore.userDisplayName)
          }

          // 如果房间正在游戏中，获取画布数据并开始游戏
          if (roomStore.currentRoom?.status === 'playing') {
            await gameStore.fetchCanvasData(roomId)
            gameStore.startGame(roomId)
          }
          
          // 启动实时数据轮询（作为WebSocket的备用方案）
          startPolling()
          
          // 自动设置玩家准备状态
          autoSetPlayerReady(roomId)

          // 同步房间成员到游戏玩家列表，覆盖占位玩家
          try { roomStore.updateGamePlayersFromMembers(gameStore) } catch (_) {}

          // 周期性确保SignalR组映射存在
          startEnsureGroup(roomId)

          // 取消此前的本地强制开局兜底逻辑，完全以服务端广播为准
          try { if (enterGameFallbackTimer) { clearTimeout(enterGameFallbackTimer); enterGameFallbackTimer = null } } catch (_) {}
        } catch (error) {
          console.error('加载房间信息失败:', error)
        }
      } else if (roomStore.currentRoom && roomStore.currentRoom.roomId) {
        // 如果store中已有房间信息（从首页跳转过来），直接使用
        const currentRoomId = roomStore.currentRoom.roomId
        console.log('使用store中的房间信息:', currentRoomId)
        gameStore.setCurrentRoom(currentRoomId, roomStore.currentRoom.roomName, roomStore.currentRoom.maxPlayers, roomStore.currentRoom.gameDuration)

        // 确保已加入SignalR房间组，建立连接ID到玩家ID的映射
        if (socketManager.getConnectionStatus().isConnected) {
          console.log('加入SignalR房间组以建立映射...')
          await socketManager.joinRoom(currentRoomId, userStore.userDisplayName)
        }

        // 如果房间正在游戏中，获取画布数据并开始游戏
        if (roomStore.currentRoom.status === 'playing') {
          await gameStore.fetchCanvasData(currentRoomId)
          gameStore.startGame(currentRoomId)
        }
        
        // 启动实时数据轮询（作为WebSocket的备用方案）
        startPolling()
        
        // 自动设置玩家准备状态
        autoSetPlayerReady(currentRoomId)

        // 同步房间成员到游戏玩家列表，覆盖占位玩家
        try { roomStore.updateGamePlayersFromMembers(gameStore) } catch (_) {}

        // 周期性确保SignalR组映射存在
        startEnsureGroup(currentRoomId)
      } else {
        console.log('没有有效的房间信息，显示创建房间界面')
      }
    })

    // 页面卸载时清理
    onUnmounted(() => {
      // 移除网络状态监听器
      window.removeEventListener('online', handleOnline)
      window.removeEventListener('offline', handleOffline)
      
      // 清理网络错误计数定时器
      if (resetNetworkErrorTimer) {
        clearInterval(resetNetworkErrorTimer)
        resetNetworkErrorTimer = null
      }
      
      // 停止实时数据轮询
      stopPolling()
      
      // 清理所有WebSocket事件监听器
      socketManager.off('RoomMembersUpdated')
      socketManager.off('RoomStatusChanged')
      socketManager.off('PlayerReadyChanged')
      socketManager.off('MemberReadyChanged')
      socketManager.off(GAME_EVENTS.GAME_STARTED)
      socketManager.off(GAME_EVENTS.ROOM_JOINED)
      socketManager.off(GAME_EVENTS.PLAYER_JOINED)
      socketManager.off('PlayerLeft')
      socketManager.off('GameStatusUpdated')
      socketManager.off('PaintAction')
      socketManager.off(GAME_EVENTS.CANVAS_CLEARED)
      socketManager.off(GAME_EVENTS.GAME_ENDED)
      socketManager.off('PlayerScoreUpdated')
      socketManager.off('LeaderboardUpdated')
      socketManager.off('GameCountdown')
      socketManager.off('GameStartFailed')
      
      // 移除window事件监听器
      window.removeEventListener('PaintAction', () => {})
      
      // 断开WebSocket连接
      socketManager.disconnect()
      
      // 清理全局标记
      window._gameViewListenersSetup = false
      
      console.log('🧹 GameView组件已卸载，资源已清理')
      if (ensureGroupTimer) { clearInterval(ensureGroupTimer); ensureGroupTimer = null }
    })

    // 返回所有需要在模板中使用的属性和方法
    const canvasDataVersion = ref(0)

    // 调试面板显示控制
    const showDebugPanel = ref(false)
    
    // 强制重连Socket
    const forceReconnect = async () => {
      try {
        console.log('🔄 强制重连Socket...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
        await socketManager.connect()
        console.log('✅ 强制重连完成')
      } catch (error) {
        console.error('❌ 强制重连失败:', error)
      }
    }
    
    // 强制加入房间组
    const forceJoinRoom = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (roomId) {
          console.log('🔗 强制加入房间组:', roomId)
          const success = await socketManager.ensureJoinRoomGroup(roomId)
          if (success) {
            console.log('✅ 强制加入房间组成功')
          } else {
            console.warn('⚠️ 强制加入房间组失败')
          }
        }
      } catch (error) {
        console.error('❌ 强制加入房间组失败:', error)
      }
    }
    
    // 清理无效玩家数据
    const cleanupInvalidPlayers = () => {
      try {
        console.log('🧹 开始清理无效玩家数据...')
        console.log('清理前玩家列表:', gameStore.players)
        gameStore.cleanupPlayers()
        console.log('清理后玩家列表:', gameStore.players)
        ElMessage.success('无效玩家数据已清理')
      } catch (error) {
        console.error('❌ 清理玩家数据失败:', error)
        ElMessage.error('清理玩家数据失败')
      }
    }
    
    // 切换调试面板显示
    const toggleDebugPanel = () => {
      showDebugPanel.value = !showDebugPanel.value
    }
    
    // 格式化更新时间
    const formatUpdateTime = (time) => {
      if (!time) return 'N/A'
      return time.toLocaleTimeString()
    }
    
    // 添加键盘快捷键显示调试面板 (Ctrl+Shift+D)
    onMounted(() => {
      const handleKeyDown = (e) => {
        if (e.ctrlKey && e.shiftKey && e.key === 'D') {
          e.preventDefault()
          toggleDebugPanel()
        }
      }
      document.addEventListener('keydown', handleKeyDown)
      
      // 清理事件监听器
      onUnmounted(() => {
        document.removeEventListener('keydown', handleKeyDown)
      })
    })

    // 测试绘画同步
    const testPaintSync = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (!roomId) {
          ElMessage.warning('没有房间ID，无法测试')
          return
        }
        
        console.log('🎨 开始测试绘画同步...')
        console.log('🎨 房间ID:', roomId)
        console.log('🎨 Socket状态:', socketManager.getConnectionStatus())
        console.log('🎨 已加入房间组:', socketManager.getCurrentJoinedRoomId())
        
        // 发送一个测试绘画动作
        const testPayload = {
          roomId: roomId,
          x: 100,
          y: 100,
          color: '#FF0000',
          tool: 'brush',
          playerId: userStore.user?.id || userStore.userId,
          playerName: userStore.user?.userName || 'TestUser',
          brushSize: 5
        }
        
        console.log('🎨 发送测试绘画动作:', testPayload)
        const success = await socketManager.paintAction(testPayload)
        
        if (success) {
          console.log('✅ 测试绘画动作发送成功')
          ElMessage.success('测试绘画动作已发送，请检查其他窗口是否收到')
        } else {
          console.error('❌ 测试绘画动作发送失败')
          ElMessage.error('测试绘画动作发送失败')
        }
      } catch (error) {
        console.error('❌ 测试绘画同步失败:', error)
        ElMessage.error('测试绘画同步失败: ' + error.message)
      }
    }
    
    // 强制同步画布
    const forceSyncCanvas = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (!roomId) {
          ElMessage.warning('没有房间ID，无法同步')
          return
        }
        
        console.log('🔄 开始强制同步画布...')
        console.log('🔄 房间ID:', roomId)
        console.log('🔄 当前画布像素数:', Object.keys(gameStore.canvasData.pixels || {}).length)
        
        // 强制重新获取画布数据
        await gameStore.fetchCanvasData(roomId)
        console.log('✅ 画布数据已重新获取')
        
        // 强制重新计算玩家面积
        gameStore.recalculateAllPlayerAreas()
        console.log('✅ 玩家面积已重新计算')
        
        // 更新Canvas版本号触发重绘
        canvasDataVersion.value++
        console.log('✅ Canvas版本号已更新:', canvasDataVersion.value)
        
        ElMessage.success('画布已强制同步')
      } catch (error) {
        console.error('❌ 强制同步画布失败:', error)
        ElMessage.error('强制同步画布失败: ' + error.message)
      }
    }

    // 强制重置游戏状态
    const forceResetGameState = async () => {
      try {
        console.log('🔄 强制重置游戏状态...')
        await gameStore.resetGame()
        ElMessage.success('游戏状态已强制重置')
      } catch (error) {
        console.error('强制重置游戏状态失败:', error)
        ElMessage.error('强制重置游戏状态失败: ' + error.message)
      }
    }

    // 强制清理所有数据
    const forceCleanAllData = () => {
      try {
        console.log('🧹 开始强制清理所有数据...')
        
        // 1. 清理游戏状态
        gameStore.resetGame()
        console.log('✅ 游戏状态已重置')
        
        // 2. 清理房间状态
        if (roomStore.currentRoom) {
          roomStore.currentRoom.status = 'waiting'
          console.log('✅ 房间状态已重置')
        }
        
        // 3. 强制清理玩家数据
        gameStore.cleanupPlayers()
        console.log('✅ 玩家数据已清理')
        
        // 4. 重置Canvas版本号
        canvasDataVersion.value = 0
        console.log('✅ Canvas版本号已重置')
        
        // 5. 强制重新加入房间组
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (roomId && socketManager.getConnectionStatus().isConnected) {
          socketManager.ensureJoinRoomGroup(roomId).then(success => {
            if (success) {
              console.log('✅ 房间组重新加入成功')
            } else {
              console.warn('⚠️ 房间组重新加入失败')
            }
          })
        }
        
        ElMessage.success('所有数据已强制清理')
      } catch (error) {
        console.error('❌ 强制清理数据失败:', error)
        ElMessage.error('强制清理数据失败: ' + error.message)
      }
    }

    // 强制重新初始化Socket
    const forceReinitSocket = async () => {
      try {
        console.log('�� 强制重新初始化Socket...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
        await socketManager.connect()
        console.log('✅ Socket已重新初始化')
      } catch (error) {
        console.error('❌ 强制重新初始化Socket失败:', error)
        ElMessage.error('强制重新初始化Socket失败: ' + error.message)
      }
    }

    // 重置Socket事件监听器
    const resetSocketListeners = () => {
      // 清理所有事件监听器
      socketManager.off('RoomMembersUpdated')
      socketManager.off('RoomStatusChanged')
      socketManager.off('PlayerReadyChanged')
      socketManager.off('MemberReadyChanged')
      socketManager.off(GAME_EVENTS.GAME_STARTED)
      socketManager.off(GAME_EVENTS.ROOM_JOINED)
      socketManager.off(GAME_EVENTS.PLAYER_JOINED)
      socketManager.off('PlayerLeft')
      socketManager.off('GameStatusUpdated')
      socketManager.off('PaintAction')
      socketManager.off(GAME_EVENTS.CANVAS_CLEARED)
      socketManager.off(GAME_EVENTS.GAME_ENDED)
      socketManager.off('PlayerScoreUpdated')
      socketManager.off('LeaderboardUpdated')
      socketManager.off('GameCountdown')
      socketManager.off('GameStartFailed')
      
      // 重新设置事件监听器
      setupWebSocketListeners()
      console.log('🎧 Socket 事件监听器已重置')
    }

    // 一键修复所有问题
    const oneClickFixAll = async () => {
      try {
        console.log('🚀 开始一键修复所有问题...')
        
        // 1. 强制清理所有数据
        console.log('步骤1: 清理所有数据...')
        gameStore.resetGame()
        if (roomStore.currentRoom) {
          roomStore.currentRoom.status = 'waiting'
        }
        gameStore.cleanupPlayers()
        canvasDataVersion.value = 0
        
        // 2. 强制重新初始化Socket
        console.log('步骤2: 重新初始化Socket...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 1000))
        await socketManager.connect()
        
        // 3. 重置事件监听器
        console.log('步骤3: 重置事件监听器...')
        resetSocketListeners()
        
        // 4. 强制加入房间组
        console.log('步骤4: 强制加入房间组...')
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (roomId) {
          const joinSuccess = await socketManager.ensureJoinRoomGroup(roomId)
          if (joinSuccess) {
            console.log('✅ 房间组加入成功')
          } else {
            console.warn('⚠️ 房间组加入失败')
          }
        }
        
        // 5. 强制同步画布
        console.log('步骤5: 强制同步画布...')
        if (roomId) {
          await gameStore.fetchCanvasData(roomId)
          gameStore.recalculateAllPlayerAreas()
        }
        
        console.log('✅ 一键修复完成!')
        ElMessage.success('所有问题已修复，请测试绘画同步')
        
      } catch (error) {
        console.error('❌ 一键修复失败:', error)
        ElMessage.error('一键修复失败: ' + error.message)
      }
    }

    // 强制重建连接
    const forceRebuildConnection = async () => {
      try {
        console.log('🔨 强制重建连接...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
        await socketManager.connect()
        console.log('✅ 连接已重建')
      } catch (error) {
        console.error('❌ 重建连接失败:', error)
        ElMessage.error('重建连接失败: ' + error.message)
      }
    }

    // 诊断Socket连接
    const diagnoseSocketConnection = () => {
      console.log('🔍 开始诊断Socket连接...')
      
      // 1. 检查Socket连接状态
      const connectionStatus = socketManager.getConnectionStatus()
      console.log('🔍 Socket连接状态:', connectionStatus)
      
      // 2. 检查房间信息
      const roomId = route.params.roomId || currentRoom.value?.roomId
      console.log('🔍 当前房间ID:', roomId)
      console.log('🔍 房间信息:', currentRoom.value)
      
      // 3. 检查房间组状态
      const joinedRoomId = socketManager.getCurrentJoinedRoomId()
      console.log('🔍 已加入房间组:', joinedRoomId)
      
      // 4. 检查游戏状态
      console.log('🔍 游戏状态:', gameStore.gameStatus)
      console.log('🔍 房间状态:', roomStore.currentRoom?.status)
      
      // 5. 检查玩家数据
      console.log('🔍 玩家列表:', gameStore.players)
      console.log('🔍 画布像素数:', Object.keys(gameStore.canvasData.pixels || {}).length)
      
      // 6. 检查事件监听器
      console.log('🔍 事件监听器状态:', window._gameViewListenersSetup)
      
      // 7. 生成诊断报告
      const diagnosis = {
        socketConnected: connectionStatus.isConnected,
        socketStatus: connectionStatus.status,
        hasRoomId: !!roomId,
        roomIdMatch: roomId === joinedRoomId,
        gameStatus: gameStore.gameStatus,
        roomStatus: roomStore.currentRoom?.status,
        playerCount: gameStore.players.length,
        canvasPixelCount: Object.keys(gameStore.canvasData.pixels || {}).length,
        listenersSetup: window._gameViewListenersSetup
      }
      
      console.log('🔍 诊断报告:', diagnosis)
      
      // 8. 显示诊断结果
      let message = '诊断完成！'
      if (!diagnosis.socketConnected) {
        message += ' Socket未连接！'
      }
      if (!diagnosis.roomIdMatch) {
        message += ' 房间组未正确加入！'
      }
      if (diagnosis.gameStatus !== 'playing') {
        message += ' 游戏状态异常！'
      }
      
      ElMessage.info(message)
      
      return diagnosis
    }

    // 测试后端连接
    const testBackendConnection = async () => {
      try {
        console.log('🌐 开始测试后端连接...')
        const response = await fetch('/api/test')
        if (response.ok) {
          console.log('🌐 后端连接测试成功')
          ElMessage.success('后端连接测试成功')
        } else {
          console.error('🌐 后端连接测试失败:', response.statusText)
          ElMessage.error('后端连接测试失败')
        }
      } catch (error) {
        console.error('🌐 后端连接测试失败:', error)
        ElMessage.error('后端连接测试失败')
      }
    }

    // 强制重建所有连接
    const forceRebuildAllConnections = async () => {
      try {
        console.log('⚡ 开始强制重建所有连接...')
        
        // 1. 完全断开所有连接
        console.log('步骤1: 断开所有连接...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 2000)) // 等待2秒
        
        // 2. 清理所有状态
        console.log('步骤2: 清理所有状态...')
        gameStore.resetGame()
        if (roomStore.currentRoom) {
          roomStore.currentRoom.status = 'waiting'
        }
        gameStore.cleanupPlayers()
        canvasDataVersion.value = 0
        
        // 3. 重新建立Socket连接
        console.log('步骤3: 重新建立Socket连接...')
        await socketManager.connect()
        await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
        
        // 4. 重新设置事件监听器
        console.log('步骤4: 重新设置事件监听器...')
        window._gameViewListenersSetup = false // 重置标志
        setupWebSocketListeners()
        
        // 5. 强制加入房间组
        console.log('步骤5: 强制加入房间组...')
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (roomId) {
          const joinSuccess = await socketManager.ensureJoinRoomGroup(roomId)
          if (joinSuccess) {
            console.log('✅ 房间组加入成功')
          } else {
            console.warn('⚠️ 房间组加入失败')
          }
        }
        
        // 6. 强制同步画布
        console.log('步骤6: 强制同步画布...')
        if (roomId) {
          await gameStore.fetchCanvasData(roomId)
          gameStore.recalculateAllPlayerAreas()
        }
        
        console.log('✅ 所有连接重建完成!')
        ElMessage.success('所有连接已重建，请测试绘画同步')
        
      } catch (error) {
        console.error('❌ 强制重建所有连接失败:', error)
        ElMessage.error('强制重建所有连接失败: ' + error.message)
      }
    }

    // 强制重置所有事件监听器
    const forceResetAllEventListeners = () => {
      // 清理所有事件监听器
      socketManager.off('RoomMembersUpdated')
      socketManager.off('RoomStatusChanged')
      socketManager.off('PlayerReadyChanged')
      socketManager.off('MemberReadyChanged')
      socketManager.off(GAME_EVENTS.GAME_STARTED)
      socketManager.off(GAME_EVENTS.ROOM_JOINED)
      socketManager.off(GAME_EVENTS.PLAYER_JOINED)
      socketManager.off('PlayerLeft')
      socketManager.off('GameStatusUpdated')
      socketManager.off('PaintAction')
      socketManager.off(GAME_EVENTS.CANVAS_CLEARED)
      socketManager.off(GAME_EVENTS.GAME_ENDED)
      socketManager.off('PlayerScoreUpdated')
      socketManager.off('LeaderboardUpdated')
      socketManager.off('GameCountdown')
      socketManager.off('GameStartFailed')
      
      // 重新设置事件监听器
      setupWebSocketListeners()
      console.log('🎧 Socket 事件监听器已重置')
    }

    // 强制测试绘画同步
    const forceTestPaintSync = async () => {
      try {
        const roomId = route.params.roomId || currentRoom.value?.roomId
        if (!roomId) {
          ElMessage.warning('没有房间ID，无法测试')
          return
        }
        
        console.log('🎨 开始强制测试绘画同步...')
        console.log('🎨 房间ID:', roomId)
        console.log('🎨 Socket状态:', socketManager.getConnectionStatus())
        console.log('🎨 已加入房间组:', socketManager.getCurrentJoinedRoomId())
        
        // 发送一个强制测试绘画动作
        const testPayload = {
          roomId: roomId,
          x: 100,
          y: 100,
          color: '#FF0000',
          tool: 'brush',
          playerId: userStore.user?.id || userStore.userId,
          playerName: userStore.user?.userName || 'TestUser',
          brushSize: 5
        }
        
        console.log('🎨 发送强制测试绘画动作:', testPayload)
        const success = await socketManager.paintAction(testPayload)
        
        if (success) {
          console.log('✅ 强制测试绘画动作发送成功')
          ElMessage.success('强制测试绘画动作已发送，请检查其他窗口是否收到')
        } else {
          console.error('❌ 强制测试绘画动作发送失败')
          ElMessage.error('强制测试绘画动作发送失败')
        }
      } catch (error) {
        console.error('❌ 强制测试绘画同步失败:', error)
        ElMessage.error('强制测试绘画同步失败: ' + error.message)
      }
    }

    // 强制清理多余玩家
    const forceCleanupExtraPlayers = () => {
      try {
        console.log('🧹 开始强制清理多余玩家数据...')
        console.log('清理前玩家列表:', gameStore.players)
        gameStore.cleanupExtraPlayers()
        console.log('清理后玩家列表:', gameStore.players)
        ElMessage.success('多余玩家数据已清理')
      } catch (error) {
        console.error('❌ 清理多余玩家数据失败:', error)
        ElMessage.error('清理多余玩家数据失败')
      }
    }

    // 强制重建完整连接
    const forceRebuildCompleteConnection = async () => {
      try {
        console.log('🔧 强制重建完整连接...')
        await socketManager.disconnect()
        await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
        await socketManager.connect()
        console.log('✅ 完整连接已重建')
      } catch (error) {
        console.error('❌ 重建完整连接失败:', error)
        ElMessage.error('重建完整连接失败: ' + error.message)
      }
    }

    // 强制完全重置事件监听器
    const forceResetAllEventListenersCompletely = () => {
      // 清理所有事件监听器
      socketManager.off('RoomMembersUpdated')
      socketManager.off('RoomStatusChanged')
      socketManager.off('PlayerReadyChanged')
      socketManager.off('MemberReadyChanged')
      socketManager.off(GAME_EVENTS.GAME_STARTED)
      socketManager.off(GAME_EVENTS.ROOM_JOINED)
      socketManager.off(GAME_EVENTS.PLAYER_JOINED)
      socketManager.off('PlayerLeft')
      socketManager.off('GameStatusUpdated')
      socketManager.off('PaintAction')
      socketManager.off(GAME_EVENTS.CANVAS_CLEARED)
      socketManager.off(GAME_EVENTS.GAME_ENDED)
      socketManager.off('PlayerScoreUpdated')
      socketManager.off('LeaderboardUpdated')
      socketManager.off('GameCountdown')
      socketManager.off('GameStartFailed')
      
      // 重新设置事件监听器
      setupWebSocketListeners()
      console.log('🎧 Socket 事件监听器已重置')
    }

    return {
      // 状态
      gameStatus,
      gameTime,
      currentRoom,
      showRoomDialog,
      showStats,
      showRoomInfo,
      isOnline,
      networkErrorCount,
      isTestingNetwork,
      canvasDataVersion,
      brushSize,
      isMockMode,
      players,
      canvasData,
      
      // 计算属性
      colors,
      selectedColor,
      activePlayerCount,
      isReady,
      isHost,
      allPlayersReady,
      readyPlayerCount,
      totalPlayerCount,
      canStartGame,
      progressPercentage,
      winner,
      formatTime,
      
      // 方法
      handleRoomCreated,
      handleRoomJoined,
      handleLeaveRoom,
      handlePixelAdded,
      handleCanvasInitialized,
      handleCanvasStatsUpdated,
      clearMyPaint,
      testNetworkConnection,
      debugCanvas,
      getActualPlayerCount,
      enterGame,
      startGame,
      toggleReady,
      resetGame,
      showGameOverDialog,
      handleRestart,
      testConnection,
              showDebugPanel,
        forceReconnect,
        forceJoinRoom,
        cleanupInvalidPlayers,
        toggleDebugPanel,
        formatUpdateTime,
        testPaintSync,
        forceSyncCanvas,
        forceResetGameState,
        forceCleanAllData,
        forceReinitSocket,
        resetSocketListeners,
        oneClickFixAll,
        forceRebuildConnection,
        diagnoseSocketConnection,
        testBackendConnection,
        forceRebuildAllConnections,
        forceResetAllEventListeners,
        forceTestPaintSync,
        forceCleanupExtraPlayers,
        forceRebuildCompleteConnection,
        forceResetAllEventListenersCompletely
    }
  }
}
</script>

<style scoped>
.game-container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f5f5f5;
}



.main-content {
  flex: 1;
  display: flex;
  overflow: hidden;
  height: 100vh;
}

/* 等待房间样式 */
.waiting-room {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.waiting-content {
  text-align: center;
  max-width: 600px;
  padding: 40px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 20px;
  backdrop-filter: blur(10px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}

.waiting-content h1 {
  font-size: 2.5rem;
  margin-bottom: 16px;
  font-weight: 700;
}

.waiting-content p {
  font-size: 1.2rem;
  margin-bottom: 40px;
  opacity: 0.9;
}

.action-buttons {
  display: flex;
  gap: 20px;
  justify-content: center;
  margin-bottom: 40px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 32px;
  border: none;
  border-radius: 12px;
  font-size: 1.1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.action-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}

.create-btn {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
}

.join-btn {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
}

.btn-icon {
  font-size: 1.5rem;
}

.room-info {
  margin-top: 40px;
  padding: 24px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  text-align: left;
}

.room-info h3 {
  margin-bottom: 16px;
  font-size: 1.3rem;
  text-align: center;
}

.room-info p {
  margin-bottom: 8px;
  font-size: 1rem;
  opacity: 0.9;
}

/* 网络状态提示 */
.network-warning {
  background: linear-gradient(135deg, #fbbf24, #f59e0b);
  color: white;
  padding: 8px 16px;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.warning-icon {
  font-size: 1.1rem;
}

.test-network-btn {
  background: #3b82f6;
  color: white;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 0.7rem;
  cursor: pointer;
  transition: background-color 0.2s;
  margin-left: 8px;
}

.test-network-btn:hover:not(:disabled) {
  background: #2563eb;
}

.test-network-btn:disabled {
  background: #9ca3af;
  cursor: not-allowed;
}

/* 房间准备就绪提示条样式 */
.room-ready-banner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(135deg, #4f46e5, #4338ca);
  color: white;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideIn 0.5s ease-out;
}

.banner-content {
  display: flex;
  align-items: center;
  gap: 15px;
}

.banner-icon {
  font-size: 2rem;
}

.banner-text {
  font-size: 1.1rem;
  font-weight: 600;
  color: #f3f4f6;
}

.enter-game-btn {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.enter-game-btn:hover {
  background: linear-gradient(135deg, #059669, #047857);
}

/* 游戏开始提示条样式 */
.game-start-banner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideIn 0.5s ease-out;
}

.start-game-btn {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.start-game-btn:hover {
  background: linear-gradient(135deg, #059669, #047857);
}

/* 游戏进行中提示条样式 */
.game-playing-banner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideIn 0.5s ease-out;
}

.game-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 150px;
  height: 20px;
  background-color: #e0e0e0;
  border-radius: 10px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background: linear-gradient(135deg, #10b981, #059669);
  border-radius: 10px;
  transition: width 0.3s ease-in-out;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(135deg, #059669, #047857);
  border-radius: 10px;
  transition: width 0.3s ease-in-out;
}

.progress-text {
  font-size: 0.9rem;
  font-weight: 600;
  color: #f3f4f6;
}

/* 游戏结束提示条样式 */
.game-finished-banner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(135deg, #ef4444, #dc2626);
  color: white;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideIn 0.5s ease-out;
}

.game-finished-banner .banner-content {
  display: flex;
  align-items: center;
  gap: 15px;
}

.game-finished-banner .banner-icon {
  font-size: 2rem;
}

.game-finished-banner .banner-text {
  font-size: 1.1rem;
  font-weight: 600;
  color: #f3f4f6;
}

.game-finished-banner .host-actions {
  display: flex;
  gap: 10px;
}

.game-finished-banner .reset-btn {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.game-finished-banner .reset-btn:hover {
  background: linear-gradient(135deg, #059669, #047857);
}

/* 顶部控制栏样式 */
.top-controls {
  position: relative;
  z-index: 999;
}

.top-controls.with-banner {
  margin-top: 60px; /* 为提示条留出空间 */
}

@keyframes slideIn {
  from {
    transform: translateY(-100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}


/* 获胜公告样式 */
.winner-announcement {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: linear-gradient(135deg, #fef3c7, #fde68a);
  border: 3px solid #f59e0b;
  border-radius: 20px;
  padding: 30px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
  z-index: 2000;
  animation: winnerAppear 0.5s ease-out;
}

.winner-content {
  display: flex;
  align-items: center;
  gap: 20px;
  text-align: center;
}

.winner-icon {
  font-size: 60px;
  animation: trophyBounce 1s ease-in-out infinite;
}

.winner-text h3 {
  margin: 0 0 10px 0;
  color: #92400e;
  font-size: 28px;
  font-weight: bold;
}

.winner-text p {
  margin: 0;
  color: #a16207;
  font-size: 18px;
  font-weight: 600;
}

@keyframes winnerAppear {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5);
  }
  100% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes trophyBounce {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

/* SignalR连接状态提示样式 */
.connection-status-banner {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: linear-gradient(135deg, #10b981, #059669); /* 绿色连接状态 */
  color: white;
  padding: 12px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
  animation: slideIn 0.5s ease-out;
}

.connection-status-banner.disconnected {
  background: linear-gradient(135deg, #ef4444, #dc2626); /* 红色断开状态 */
}

.connection-status-banner.reconnecting {
  background: linear-gradient(135deg, #fbbf24, #f59e0b); /* 黄色重连状态 */
}

.banner-content {
  display: flex;
  align-items: center;
  gap: 15px;
}

.status-icon {
  font-size: 2rem;
}

.status-text {
  font-size: 1.1rem;
  font-weight: 600;
  color: #f3f4f6;
}

.reconnect-btn {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.reconnect-btn:hover {
  background: linear-gradient(135deg, #2563eb, #1d4ed8);
}

.reconnect-btn:disabled {
  background: #9ca3af;
  cursor: not-allowed;
}

.waiting-text {
  background: linear-gradient(135deg, #10b981, #059669);
  color: white;
  padding: 10px 20px;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% {
    opacity: 1;
  }
  50% {
    opacity: 0.8;
  }
}

@media (max-width: 768px) {
  .waiting-content {
    padding: 24px;
    margin: 20px;
  }

  .waiting-content h1 {
    font-size: 2rem;
  }

  .action-buttons {
    flex-direction: column;
    gap: 16px;
  }

  .action-btn {
    padding: 14px 24px;
    font-size: 1rem;
  }
}

.test-connection-btn {
  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s;
  border: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  margin-left: 10px;
}

.test-connection-btn:hover {
  background: linear-gradient(135deg, #7c3aed, #6d28d9);
}

.test-connection-btn:disabled {
  background: #9ca3af;
  cursor: not-allowed;
}

/* 调试信息面板样式 */
.debug-panel {
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 10px;
  padding: 20px;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
  z-index: 1000;
}

.debug-item {
  margin-bottom: 10px;
  font-size: 1rem;
  color: #333;
}

.debug-btn {
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 0.7rem;
  cursor: pointer;
  transition: background-color 0.2s;
  margin-left: 10px;
}

.debug-btn:hover {
  background: linear-gradient(135deg, #2563eb, #1d4ed8);
}
</style>